package com.lcx.exbean;

import com.lcx.annotation.IOCValue;
import com.lcx.annotation.JsObject;
import com.lcx.constact.ConfigEnum;
import com.lcx.util.ClassLoaderUtil;
import com.lcx.util.ConfigUtil;
import com.lcx.util.ReflectUtil;

import java.io.File;

/**
 * 内置日志输出
 */
@IOCValue
@JsObject(name = "logger")
public class LogBean {

    private Object logger;

    private static Class<?> loggerClass;

    private static Class<?> loggerFactoryClass;

    private LogBean(Object logger){this.logger = logger;}

    public LogBean(){
        init();
        try {
            this.logger = getLoggerInner(LogBean.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private LogBean(int i){}

    public static LogBean getLogger(Class<?> clazz){
        LogBean log = null;
        if(clazz!=null){
            init();
            try{
                log = new LogBean(1);
                log.logger = getLoggerInner(clazz);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return log==null?new LogBean(1):log;
    }

    private static Object getLoggerInner(Class<?> clazz) throws Exception{
        return ReflectUtil.invokeMethod(loggerFactoryClass,null,"getLogger",new Class[]{Class.class},clazz);
    }

    private static void init(){
        if(loggerClass == null){
            synchronized (LogBean.class){
                if(loggerClass == null){
                    String path = ConfigUtil.getProperty(ConfigEnum.LOGGER_PATH);
                    if(path != null && !path.isEmpty()){
                        String paths[] = path.split(",");
                        for(int i=0;i<paths.length;i++){
                            paths[i] = new File(paths[i]).getAbsolutePath().replaceAll("\\\\","/");
                        }
                        try{
                            loggerClass = ClassLoaderUtil.loadClass(paths,"org.slf4j.Logger");
                            loggerFactoryClass = ClassLoaderUtil.loadClassFromCurrentThread("org.slf4j.LoggerFactory");
                        }catch (Exception e){

                        }
                    }
                }
                if(loggerClass == null || loggerFactoryClass == null){
                    System.out.println("warning:No logger found!");
                }
            }
        }
    }

    @JsObject
    public void debug(String info,Object... args){
        if(logger != null)
        ReflectUtil.invokeMethod(logger.getClass(),logger,"debug",new Class[]{String.class,Object[].class},info,args);
    }

    public void debug(String info,Throwable e){
        if(logger != null)
        ReflectUtil.invokeMethod(logger.getClass(),logger,"debug",new Class[]{String.class,Throwable.class},info,e);
    }

    @JsObject
    public void info(String info,Object... args){
        if(logger != null)
        ReflectUtil.invokeMethod(logger.getClass(),logger,"info",new Class[]{String.class,Object[].class},info,args);
    }

    public void info(String info,Throwable e){
        if(logger != null)
        ReflectUtil.invokeMethod(logger.getClass(),logger,"info",new Class[]{String.class,Throwable.class},info,e);
    }

    @JsObject
    public void warn(String info,Object... args){
        if(logger != null)
        ReflectUtil.invokeMethod(logger.getClass(),logger,"warn",new Class[]{String.class,Object[].class},info,args);
    }

    public void warn(String info,Throwable e){
        ReflectUtil.invokeMethod(logger.getClass(),logger,"warn",new Class[]{String.class,Throwable.class},info,e);
    }

    @JsObject
    public void error(String info,Object... args){
        if(logger != null)
        ReflectUtil.invokeMethod(logger.getClass(),logger,"error",new Class[]{String.class,Object[].class},info,args);
    }

    public void error(String info,Throwable e){
        if(logger != null)
        ReflectUtil.invokeMethod(logger.getClass(),logger,"error",new Class[]{String.class,Throwable.class},info,e);
    }

}
